
package control;

import exceptions.*;
import java.util.ArrayList;
import services.*;
import util.EnumSearchParameter;
import vo.*;

/**
 *
 * @author sbaldrich
 */


public class Controller {

    private static Controller INSTANCE;
    private Controller (){};
    public static Controller getInstance()
    {
        if(INSTANCE == null)
            INSTANCE = new Controller();
        return INSTANCE;
    }

    private static UserService us;
    private static UserService getUserService()
    {
        if(us == null)
            us = new UserService();
        return us;
    }

    private static ContestService cs;
    private static ContestService getContestService()
    {
        if(cs == null)
            cs = new ContestService();
        return cs;
    }

    private static ProblemService ps;
    private static ProblemService getProblemService()
    {
        if(ps == null)
            ps = new ProblemService();
        return ps;
    }

    private static KeywordService ks;
    private static KeywordService getKeywordService()
    {
        if(ks == null)
            ks = new KeywordService();
        return ks;
    }

    private static SubmissionService ss;
    private static SubmissionService getSubmissionService()
    {
        if(ss == null)
            ss = new SubmissionService();
        return ss;
    }

    /*
     * User Services
     */

    public boolean login(String handle , String password)throws Exception
    {
        us = getUserService();
        VOUser user;
        try
        {
            user = us.find(handle);
            if(user.getPassword().compareTo(password)==0)
                return true;
            return false;
        } 
        catch (Exception e)
        {
            if(e instanceof DatabaseException)
                throw e;
            return false;
        }
    }

    public boolean register(VOUser vo)throws Exception
    {
        us = getUserService();
        try
        {
            us.save(vo);
            return true;
        } catch (Exception e)
        {
            throw e;
        }
    }

    public boolean registerForContest(String handle , String contestCode)throws Exception
    {
        cs = getContestService();
        try
        {
            cs.addUser(contestCode ,handle);
            return true;
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    public boolean editUser(VOUser vo)throws Exception
    {
        us = getUserService();
        try
        {
            us.update(vo);
            return true;
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    public boolean deleteUser(VOUser vo)throws Exception
    {
        us = getUserService();
        try
        {
            us.delete(vo);
            return true;
        } catch (Exception e)
        {
            throw e;
        }
    }

    public VOUser findUser(String handle)throws Exception
    {
        us = getUserService();
        try
        {
            return us.find(handle);
        } catch (Exception e)
        {
            if(e instanceof DatabaseException)
                throw e;
            return null;
        }
    }

    public ArrayList<VOUser> listUsers(EnumSearchParameter parameter, String value) throws Exception
    {
        us = getUserService();
        try
        {
            return us.findAll(parameter,value);
        } catch (Exception e)
        {
            if(e instanceof DatabaseException)
                throw e;
            return null;
        }
    }

    public ArrayList<VOUser> listUsers() throws Exception
    {
        us = getUserService();
        try
        {
            return us.findAll();
        } catch (Exception e)
        {
            if(e instanceof DatabaseException)
                throw e;
            return null;
        }
    }

    /*
     * End User services
     */

    /*
     * Contest Services
     */

     public boolean createContest(VOContest vo)throws Exception
     {
        cs = getContestService();
        try
        {
            cs.save(vo);
            return true;
        }
        catch (Exception e)
        {
            throw e;
        }
     }

     public boolean editContest(VOContest vo)throws Exception
     {
         cs = getContestService();
         try
         {
             cs.update(vo);
             return true;
         } catch (Exception e)
         {
             throw e;
         }
     }

     public boolean deleteContest(VOContest vo)throws Exception
     {
        cs = getContestService();
         try
         {
            cs.delete(vo);
            return true;
         }
         catch (Exception e)
         {
            throw e;
         }
     }

     public VOContest findContest(String contestCode) throws Exception
     {
        cs = getContestService();
         try
         {
            return cs.find(contestCode);
         } catch (Exception e)
         {
            if(e instanceof DatabaseException)
                throw e;
            return null;
         }
     }

     public boolean endContest(String contestCode)throws Exception
     {
        cs = getContestService();
         try
         {
            cs.endContest(contestCode);
            return true;
         }
         catch (Exception e)
         {
             throw e;
         }
     }

     public ArrayList<VOScoreboard> getScoreBoard(String contestCode)throws Exception
     {
          cs = getContestService();
          try
          {
             return cs.getScoreboard(contestCode);
          }
          catch (Exception e)
          {
              throw e;
          }
     }

    /*
     * End Contest services
     */

    /*
     * Problem Services
     */

     public boolean createProblem(VOProblem vo)throws Exception
     {
         ps = getProblemService();
         try
         {
            ps.save(vo);
            return true;
         }
         catch (Exception e)
         {
             throw e;
         }
     }

     public boolean deleteProblem(VOProblem vo)throws Exception
     {
        ps = getProblemService();
         try
         {
            ps.delete(vo);
            return true;
         }
         catch (Exception e)
         {
            throw e;
         }
     }

     public VOProblem findProblem(String problemCode)throws Exception
     {
        ps = getProblemService();
        try
         {
             return ps.find(problemCode);
         }
         catch (Exception e)
         {
            if(e instanceof DatabaseException)
                throw e;
            return null;
         }
     }

     public boolean editProblem(VOProblem vo)throws Exception
     {
        ps = getProblemService();
         try
         {
             ps.update(vo);
             return true;
         }
         catch (Exception e)
         {
             throw e;
         }
     }

     public ArrayList<VOProblem> listProblems()throws Exception
     {
        ps = getProblemService();
         try
         {
            return ps.findall();
         }
         catch (Exception e)
         {
            if( e instanceof DatabaseException)
                throw e;
            return null;
         }
     }

    /*
     * End Problem services
     */

     /*
      * Keyword services
      */

     public boolean createKeyword(VOKeyword vo)throws Exception
     {
        ks = getKeywordService();
         try
         {
             ks.save(vo);
             return true;
         }
         catch (Exception e)
         {
             throw e;
         }
     }

     public boolean deleteKeyword(VOKeyword vo)throws Exception
     {
        ks = getKeywordService();
         try
         {
             ks.delete(vo);
             return true;
         }
         catch (Exception e)
         {
            throw e;
         }
     }

     public boolean editKeyword(VOKeyword vo)throws Exception
     {
        ks = getKeywordService();
         try
         {
             ks.update(vo);
             return true;
         }
         catch (Exception e)
         {
            throw e;
         }
     }

     public ArrayList<VOKeyword> listKeywords() throws Exception
     {
         try
         {
             return ks.findAll();
         }
         catch (Exception e)
         {
             if(e instanceof DatabaseException)
                 throw e;
             return null;
         }
     }

     public boolean addKeywordToProblem(String keyword , String problemcode)throws Exception
     {
        ks = getKeywordService();
         try
         {
             ks.addToProblem(keyword , problemcode);
             return true;
         }
         catch (Exception e)
         {
             throw e;
         }
     }

     /*
      * End Keyword services
      */
     /*
      * Submission services
      */

      public boolean Submit(VOSubmission vo)throws Exception
      {
          ss = getSubmissionService();
          try
          {
            ss.processSubmission(vo);
            return true;
          }
          catch (Exception e)
          {
              if(e instanceof DatabaseException
                      || e instanceof CompilationException)
                  throw e;
              return false;
          }
      }

      public ArrayList<VOSubmission> listSubmissions(EnumSearchParameter parameter, Object vo)throws Exception
      {
          ss = getSubmissionService();
          try
          {
              return ss.findAll(parameter , vo);
          } 
          catch (Exception e)
          {
              if( e instanceof DatabaseException)
                  throw e;
              return null;
          }
      }

      
     /*
      * End Submission services
      */









    public static void main(String[] args)
    {
        Controller c = Controller.getInstance();
        VOUser u = new VOUser();
        u.setHandle("SBaldrich");
        u.setCountry("Colombia");
        u.setEmail("santiago.baldrich@gmail.com");
        u.setFirstName("Santiago");
        u.setInstitution("Universidad Nacional");
        u.setIsAdmin(true);
        u.setLastName("Baldrich");
        u.setPassword("pass");
        u.setRating(1000);
        u.setTeam("UN-03");
        try {
                
            c.register(u);
            
        } catch (Exception e) {
            System.out.println("Exception: " + e.getMessage());
        }
        
        
        
//        ArrayList<VOScoreboard> sb = new ArrayList<VOScoreboard>();
//        try
//        {
//           sb = c.getScoreBoard("CODE");
//
//        } catch (Exception e) {
//            System.out.println(" :-( Try Again. :" + e.getMessage());
//        }
//        for(VOScoreboard vo : sb)
//            System.out.println(vo);
//
//
//        try
//        {
//           sb = c.getScoreBoard("CODE");
//
//        } catch (Exception e) {
//            System.out.println(" :-( Try Again. :" + e.getMessage());
//        }
//        for(VOScoreboard vo : sb)
//            System.out.println(vo);
//
//
        
    }
}
